package xcmg.device.service.buyBack;

import com.github.pagehelper.PageInfo;
import org.apache.poi.ss.usermodel.CellType;
import yb.ecp.fast.infra.util.PageHelperPlus;
import org.apache.commons.collections.CollectionUtils;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import xcmg.device.dao.entity.buyBack.BackInboundDO;
import xcmg.device.dao.entity.buyBack.BackInboundDetailDO;
import xcmg.device.dao.entity.buyBack.BackOutboundDO;
import xcmg.device.dao.entity.buyBack.BackOutboundDetailDO;
import xcmg.device.dao.entity.buyBack.BuyBackDO;
import xcmg.device.dao.entity.buyBack.BuyBackDetailDO;
import xcmg.device.dao.mapper.CompanyInfoMapper;
import xcmg.device.dao.mapper.buyBack.BackInboundDetailMapper;
import xcmg.device.dao.mapper.buyBack.BackOutboundDetailMapper;
import xcmg.device.dao.mapper.buyBack.BuyBackDetailMapper;
import xcmg.device.dao.mapper.buyBack.BuyBackMapper;
import xcmg.device.infra.DateUtil;
import xcmg.device.infra.ErrorCode;
import xcmg.device.infra.ExportUtil;
import xcmg.device.infra.FileUtil;
import xcmg.device.infra.enums.BillDesc;
import xcmg.device.service.GenDocumentService;
import xcmg.device.service.basic.MaterialsService;
import xcmg.device.service.vo.FunctionResult;
import xcmg.device.service.vo.basic.MaterialsVO;
import xcmg.device.service.vo.buyBack.BuyBackAddVO;
import xcmg.device.service.vo.buyBack.BuyBackDetialVO;
import xcmg.device.service.vo.buyBack.BuyBackVO;
import xcmg.device.service.warehouse.CommonService;
import yb.ecp.fast.feign.FastGenClient;
import yb.ecp.fast.infra.infra.ActionResult;
import yb.ecp.fast.infra.infra.PageCommonVO;
import yb.ecp.fast.infra.infra.SearchCommonVO;
import yb.ecp.fast.infra.util.ListUtil;
import yb.ecp.fast.infra.util.StringUtil;

import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import static xcmg.device.util.DecimalUtil.roundDecimal4Enter;
import static xcmg.device.util.DecimalUtil.roundDecimal4Output;

@Service
public class BuyBackService {

    @Autowired
    private BuyBackMapper buyBackMapper;

    @Autowired
    private BuyBackDetailMapper buyBackDetailMapper;

    @Autowired
    private FastGenClient fastGenClient;

    @Autowired
    private GenDocumentService genDocumentService;

    @Autowired
    private CommonService commonService;

    @Autowired
    private HttpServletResponse response;

    @Autowired
    private MaterialsService materialsService;

    @Autowired
    private CompanyInfoMapper companyInfoMapper;

    @Autowired
    private BackInboundDetailMapper backInboundDetailMapper;
    @Autowired
    private BackOutboundDetailMapper backOutboundDetailMapper;

    @Value("${spring.file.download.path}")
    private String filePath;

    private String templateExcelFileName="BuyBackImport.xls";

    @Transactional(rollbackFor = Exception.class)
    public ErrorCode add(BuyBackAddVO buyBackAddVO)throws Exception{
        if(buyBackAddVO.getHeaderInfo() == null || ListUtil.isNullOrEmpty(buyBackAddVO.getMaterialList())){
            return ErrorCode.IllegalArument;
        }
        ActionResult<String> textResult = fastGenClient.textGuid();
        if (textResult.getCode() != ErrorCode.Success.getCode()) {
            return ErrorCode.IllegalArument;
        }

        BuyBackDO buyBackDO = new BuyBackDO();
        BeanUtils.copyProperties(buyBackAddVO.getHeaderInfo(), buyBackDO);
        buyBackDO.setId(textResult.getValue());
        buyBackDO.setBackOrder(genDocumentService.getDocumentNo(BillDesc.BuyBack));
        buyBackDO.setCreateDate(new Date());
        buyBackDO.setTotalPrice(BigDecimal.ZERO);
        boolean success;

        for(BuyBackDetialVO detialVO : buyBackAddVO.getMaterialList()){
            BuyBackDetailDO detialDO = new BuyBackDetailDO();
            BeanUtils.copyProperties(detialVO, detialDO);
            detialDO.setBillId(buyBackDO.getId());

            detialDO = fillBuyBackInfo(detialDO, detialVO);
            success = buyBackDetailMapper.insert(detialDO)>0;
            if(!success){
                throw new Exception("操作失败");
            }
            buyBackDO.setTotalPrice(buyBackDO.getTotalPrice().add(detialDO.getTotalPrice()));
        }
        success = buyBackMapper.insert(buyBackDO)>0;
        if(!success){
            throw new Exception("操作失败");
        }
        return ErrorCode.Success;
    }

    private BuyBackDetailDO fillBuyBackInfo(BuyBackDetailDO detialDO, BuyBackDetialVO detialVO) {
        detialDO.setRemark(detialVO.getBackRemark());
        detialDO.setBackPrice(roundDecimal4Enter(detialVO.getBackPrice()));
        detialDO.setBackQty(detialVO.getBackQty());
        detialDO.setBackTotal(roundDecimal4Enter(
            detialVO.getBackPrice().multiply(detialVO.getBackQty())
                .setScale(2, BigDecimal.ROUND_HALF_UP)));
        return detialDO;
    }

    @Transactional(rollbackFor = Exception.class)
    public ErrorCode update(BuyBackAddVO buyBackAddVO) throws Exception{
        if(buyBackAddVO.getHeaderInfo() == null || ListUtil.isNullOrEmpty(buyBackAddVO.getMaterialList())){
            return ErrorCode.IllegalArument;
        }
        if(buyBackAddVO.getHeaderInfo().getSendStatus() > 0 || buyBackAddVO.getHeaderInfo().getCreateOutStatus() > 0){
            throw new Exception("该回购单已建入库单或出库单，无法修改");
        }
        BuyBackDO buyBackDO = new BuyBackDO();
        BeanUtils.copyProperties(buyBackAddVO.getHeaderInfo(), buyBackDO);
        buyBackDO.setTotalPrice(BigDecimal.ZERO);
        boolean success = buyBackDetailMapper.deleteByBillId(buyBackDO.getId()) > 0;
        if(!success){
            throw new Exception("操作失败");
        }

        for(BuyBackDetialVO detialVO : buyBackAddVO.getMaterialList()){
            BuyBackDetailDO detialDO = new BuyBackDetailDO();
            BeanUtils.copyProperties(detialVO, detialDO);
            detialDO.setBillId(buyBackDO.getId());
            detialDO = fillBuyBackInfo(detialDO, detialVO);
            success = buyBackDetailMapper.insert(detialDO)>0;
            if(!success){
                throw new Exception("操作失败");
            }
            buyBackDO.setTotalPrice(buyBackDO.getTotalPrice().add(detialDO.getTotalPrice()));
        }

        buyBackDO.setTempStatus(0);
        success = buyBackMapper.update(buyBackDO) > 0;
        if(!success){
            throw new Exception("操作失败");
        }

        return ErrorCode.Success;
    }

    public PageCommonVO list(SearchCommonVO<BuyBackVO> condition) {
        PageCommonVO<BuyBackVO> pageCommonVO = new PageCommonVO();
        PageHelperPlus.orderBy("create_date desc");
        PageHelperPlus.startPage(condition.getPageNum(), condition.getPageSize());
        List<BuyBackDO> doList = buyBackMapper.list(condition.getFilters());
        List<BuyBackVO> voList = new ArrayList<>();
        for (BuyBackDO entity : doList) {
            BuyBackVO model = new BuyBackVO();
            BeanUtils.copyProperties(entity, model);
            if (!condition.getFilters().getSeller()) {
                model.setPlatCompany(companyInfoMapper.item(model.getSupplierOrgId()) != null);
            }
            voList.add(model);
        }
        pageCommonVO.setPageInfo(new PageInfo(doList));
        pageCommonVO.setPageInfoList(voList);
        return pageCommonVO;
    }

    @Transactional(rollbackFor = Exception.class)
    public ErrorCode delete(List<String> ids) throws Exception{
        int num = buyBackMapper.findForDeleteByIds(ids);
        if(num > 0){
            throw new Exception("已经审核通过的回购单不能删除");
        }
        return buyBackMapper.updateDel(ids, 1)>0?ErrorCode.Success:ErrorCode.Failure;
    }

    @Transactional(rollbackFor = Exception.class)
    public ErrorCode invalid(String id) throws Exception{
        BuyBackDO buyBackDO = buyBackMapper.selectByPrimaryKey(id);
        if(buyBackDO == null){
            return ErrorCode.IllegalArument;
        }
        if(buyBackDO.getSendStatus() > 0 || buyBackDO.getCreateOutStatus() > 0){
            throw new Exception("该回购单已建入库单或出库单，无法作废");
        }
        return buyBackMapper.updateInvalid(id, 1)>0?ErrorCode.Success:ErrorCode.Failure;
    }

    @Transactional(rollbackFor = Exception.class)
    public ErrorCode audit(BuyBackVO buyBackVO, String userId) throws Exception{
        BuyBackDO buyBackDO = new BuyBackDO();
        BeanUtils.copyProperties(buyBackVO, buyBackDO);
        if(buyBackDO.getStatus() < 3){
            buyBackDO.setFirstAuditId(userId);
            buyBackDO.setFirstAuditName(commonService.getUserName(userId));
            buyBackDO.setFirstAuditDate(new Date());
        }else{
            buyBackDO.setSecondAuditId(userId);
            buyBackDO.setSecondAuditName(commonService.getUserName(userId));
            buyBackDO.setSecondAuditDate(new Date());
        }
        updateDetails(buyBackVO);
        if (null != buyBackDO.getStatus() && (buyBackDO.getStatus() == 1 || buyBackDO.getStatus() == 3)) {
            buyBackDO.setTempStatus(1);//用来控制审核按钮权限
        }
        return buyBackMapper.update(buyBackDO) > 0 ? ErrorCode.Success : ErrorCode.Failure;
    }

    private void updateDetails(BuyBackVO buyBackVO) {
        for (BuyBackDetialVO detailVO : buyBackVO.getDetailVOs()) {
            BuyBackDetailDO detailDO = new BuyBackDetailDO();
            detailDO = fillBuyBackInfo(detailDO, detailVO);
            detailDO.setBillId(buyBackVO.getId());
            detailDO.setMaterialsNo(detailVO.getMaterialsNo());
            buyBackDetailMapper.update(detailDO);
        }
    }


    public BuyBackAddVO item(String id){
        BuyBackAddVO result = new BuyBackAddVO();
        BuyBackDO buyBackDO = buyBackMapper.selectByPrimaryKey(id);
        if(buyBackDO == null){
            return result;
        }
        BuyBackVO buyBackVO = new BuyBackVO();
        BeanUtils.copyProperties(buyBackDO, buyBackVO);
        buyBackVO.setPlatCompany(companyInfoMapper.item(buyBackVO.getSupplierOrgId())!=null);
        List<BuyBackDetialVO> listVO = new ArrayList<>();
        List<BuyBackDetailDO> listDO = buyBackDetailMapper.list(id);
        BigDecimal buyBackTotal = BigDecimal.ZERO;
        for(BuyBackDetailDO entity:listDO){
            BuyBackDetialVO model = new BuyBackDetialVO();
            BeanUtils.copyProperties(entity, model);
            listVO.add(model);
            model.setBackPrice(roundDecimal4Output(entity.getBackPrice()));
            model.setBackTotal(roundDecimal4Output(entity.getBackTotal()));
            model.setBackRemark(entity.getRemark());
            model.setRemark(null);
            buyBackTotal = buyBackTotal.add(model.getBackTotal());
        }
        buyBackVO.setBuyBackTotal(buyBackTotal);
        result.setHeaderInfo(buyBackVO);
        result.setMaterialList(listVO);
        return result;
    }

    public void export(List<String> ids)throws Exception{
        invokeExport(buyBackMapper.findByIds(ids));
    }

    public void exportAll(BuyBackVO condition)throws Exception{
        Integer count = buyBackMapper.listCount(condition);
        List<BuyBackDO> dataList = new ArrayList<>();
        int times = count/500+1;
        for(int i=0; i<times; i++){
            PageHelperPlus.startPage(i + 1, 500, "create_date desc");
            dataList.addAll(buyBackMapper.list(condition));
        }
        invokeExport(dataList);
    }

    private void invokeExport(List<BuyBackDO> doList)throws Exception{
        String title = "回购单数据导出";
        String[] rowsName = new String[]{"序号","回购单号","客户名称","接收单位","调度员","总金额",
                "入库单状态","入库状态", "是否作废", "备注", "审核状态", "第一步审核人",
                "第一步审核时间", "第一步审核意见","第二步审核人", "第二步审核时间",
                "第二步审核意见", "创建人","创建时间","零件编码","零件名称","零件类型",
                "单位","单价","数量","总价","已建入库数量","已入库数量"};
        List<Object[]>  dataList = new ArrayList<>();
        Object[] objs;
        for (int i = 0; i < doList.size(); i++) {
            BuyBackDO exportDO = doList.get(i);
            List<BuyBackDetailDO>  detailDOList = buyBackDetailMapper.list(exportDO.getId());
            for(BuyBackDetailDO detailDO : detailDOList){
                objs = new Object[rowsName.length];
                objs[0] = i+1;
                objs[1] = exportDO.getBackOrder();
                objs[2] = exportDO.getPurchaseOrgName();
                objs[3] = exportDO.getSupplierOrgName();
                objs[4] = exportDO.getDispatcherName();
                objs[5] = exportDO.getTotalPrice();
                objs[6] = getSendState(exportDO.getSendStatus());
                objs[7] = getInboundState(exportDO.getInStatus());
                objs[8] = exportDO.getInvalid()==null?"否":(exportDO.getInvalid()==0?"否":"是");
                objs[9] = exportDO.getNote();
                objs[10] = getAuditState(exportDO.getStatus());
                objs[11] = exportDO.getFirstAuditName();
                objs[12] = DateUtil.formatDateTime(exportDO.getFirstAuditDate());
                objs[13] = exportDO.getFirstAuditNote();
                objs[14] = exportDO.getSecondAuditName();
                objs[15] = DateUtil.formatDateTime(exportDO.getSecondAuditDate());
                objs[16] = exportDO.getSecondAuditNote();
                objs[17] = exportDO.getCreateName();
                objs[18] = DateUtil.formatDateTime(exportDO.getCreateDate());
                objs[19] = detailDO.getMaterialsNo();
                objs[20] = detailDO.getMaterialsDes();
                objs[21] = detailDO.getMaterialsType();
                objs[22] = detailDO.getUnit();
                objs[23] = detailDO.getPrice();
                objs[24] = detailDO.getQty();
                objs[25] = detailDO.getTotalPrice();
                objs[26] = detailDO.getSendQty();
                objs[27] = detailDO.getRealQty();
                dataList.add(objs);
            }
        }
        ExportUtil exportUtil = new ExportUtil(title, rowsName, dataList);
        exportUtil.export(response);
    }

    private String getSendState(Integer state){
        switch (state){
            case 0:
                return "未申请";
            case 1:
                return "部分申请";
            case 2:
                return "已申请";
            default:
                return "未申请";
        }
    }

    private String getInboundState(Integer state){
        switch (state){
            case 0:
                return "未入库";
            case 1:
                return "部分入库";
            case 2:
                return "已入库";
            default:
                return "未入库";
        }
    }

    private String getAuditState(Integer state){
        switch (state){
            case 0:
                return "未审核";
            case 1:
                return "第一步审核拒绝";
            case 2:
                return "第一步审核通过";
            case 3:
                return "第二步审核拒绝";
            case 4:
                return "第二步审核通过";
            default:
                return "未入库";
        }
    }

    public FunctionResult importExcel(InputStream in, String orgId) throws Exception{
        FunctionResult result = new FunctionResult();
        HSSFWorkbook wb = new HSSFWorkbook(in);
        HSSFSheet sheet = wb.getSheetAt(0);

        int totalRow = sheet.getLastRowNum();
        if(totalRow < 2){
            result.setCode(ErrorCode.IllegalArument);
            result.setValue("导入模板不正确");
            return result;
        }
        int totalCell=sheet.getRow(1).getLastCellNum();
        if(totalCell != 5){
            result.setCode(ErrorCode.IllegalArument);
            result.setValue("导入模板不正确");
            return result;
        }
        List<BuyBackDetialVO> detailVOList = new ArrayList<>();
        List<BuyBackDetialVO> errorDetailVOList = new ArrayList<>();
        for (int i=2;i<=totalRow;i++){
            HSSFRow curRow=sheet.getRow(i);
            BuyBackDetialVO detailVO = new BuyBackDetialVO();
            if(curRow==null){
                continue;
            }
            String materialsNo = getCellValue(curRow, 1);
            String qty = getCellValue(curRow, 3);
            String price = getCellValue(curRow, 4);
            if(StringUtil.isNullOrEmpty(price)){
                price = "0";
            }
            if(StringUtil.isNullOrEmpty(materialsNo) && StringUtil.isNullOrEmpty(qty)){
                continue;
            }
            if(StringUtil.isNullOrEmpty(materialsNo)){
                detailVO.setErrorRow(i+1);
                detailVO.setRemark("零件编码不能为空");
                errorDetailVOList.add(detailVO);
                continue;
            }
            if(StringUtil.isNullOrEmpty(qty)){
                detailVO.setErrorRow(i+1);
                detailVO.setRemark("申请数量不能为空");
                errorDetailVOList.add(detailVO);
                continue;
            }
            if(!isInteger(qty) || "0".equals(qty)){
                detailVO.setErrorRow(i+1);
                detailVO.setRemark("申请数量格式不正确");
                errorDetailVOList.add(detailVO);
                continue;
            }
            if(new BigDecimal(qty).compareTo(BigDecimal.valueOf(99999999.99)) > 0){
                detailVO.setErrorRow(i+1);
                detailVO.setRemark("申请数量过大");
                errorDetailVOList.add(detailVO);
                continue;
            }
            if(!isInteger(price)){
                detailVO.setErrorRow(i+1);
                detailVO.setRemark("单价格式不正确");
                errorDetailVOList.add(detailVO);
                continue;
            }
            MaterialsVO materialsVO = materialsService.itemByNo(materialsNo, orgId);
            if(materialsVO==null){
                detailVO.setErrorRow(i+1);
                detailVO.setRemark("零件不存在");
                errorDetailVOList.add(detailVO);
                continue;
            }
            detailVO.setQty(new BigDecimal(qty));
            detailVO.setPrice(new BigDecimal(price));
            detailVO.setTotalPrice(detailVO.getQty().multiply(detailVO.getPrice()));
            detailVO.setMaterialsNo(materialsVO.getMaterialsNo());
            detailVO.setMaterialsDes(materialsVO.getMaterialsDes());
            detailVO.setMaterialsType(materialsVO.getMaterialsType());
            detailVO.setUnit(materialsVO.getUnit());
            detailVOList.add(detailVO);
        }

        if(ListUtil.isNullOrEmpty(errorDetailVOList)){
            result.setValue(deRepeat(detailVOList));
            result.setCode(ErrorCode.Success);
        }else{
            result.setValue(errorDetailVOList);
            result.setCode(ErrorCode.IllegalArument);
        }
        return result;
    }

    private boolean isInteger(String str) {
        if (null == str || "".equals(str)) {
            return false;
        }
        try {
            BigDecimal decimal = new BigDecimal(str);
        }catch (Exception e){
            return false;
        }
        return true;
    }

    private String getCellValue(HSSFRow curRow, int i){
        String value = "";
        if(curRow.getCell(i) != null){
            curRow.getCell(i).setCellType(CellType.STRING);
            value = curRow.getCell(i).getStringCellValue();
        }
        return value;
    }

    public static List<BuyBackDetialVO> deRepeat(List<BuyBackDetialVO> repeatList) {
        if(CollectionUtils.isEmpty(repeatList)){
            return repeatList;
        }
        for  ( int i  = 0 ; i< repeatList.size()-1;i++){
            BigDecimal sum =repeatList.get(i).getQty();
            for  ( int j=repeatList.size()-1;j>i;j -- )  {
                if  (repeatList.get(j).equals(repeatList.get(i))||repeatList.get(j).getMaterialsNo().equals(repeatList.get(i).getMaterialsNo())){
                    sum=sum.add(repeatList.get(j).getQty());
                    repeatList.remove(j);
                }
            }
            repeatList.get(i).setQty(sum);
        }
        return repeatList;
    }

    public void download() throws Exception{
        FileUtil.downLoadFile(response, filePath, templateExcelFileName);
    }

    public boolean updateSendQty(String backOrder, String materialNo, BigDecimal sendQty, String orgId){
        BuyBackDO buyBackDO = buyBackMapper.findByBackOrder(backOrder, orgId);
        if(buyBackDO == null){
            return false;
        }
        BuyBackDetailDO detailDO = buyBackDetailMapper.findBymaterialNo(buyBackDO.getId(), materialNo);
        if(detailDO == null){
            return false;
        }

        detailDO.setSendQty(sendQty);
        return buyBackDetailMapper.update(detailDO)>0;
    }

    public boolean updateCreateOutQty(String backOrder, String materialNo, BigDecimal sendQty, String orgId){
        // 订单号本身就是唯一的
        BuyBackDO buyBackDO = buyBackMapper.getByOrderNo(backOrder);
        if(buyBackDO == null){
            return false;
        }
        BuyBackDetailDO detailDO = buyBackDetailMapper.findBymaterialNo(buyBackDO.getId(), materialNo);
        if(detailDO == null){
            return false;
        }

        detailDO.setCreateOutQty(sendQty);
        return buyBackDetailMapper.update(detailDO)>0;
    }

    public boolean updateInboundEnable(String backOrder, String orgId){
        BuyBackDO buyBackDO = buyBackMapper.findByBackOrder(backOrder, orgId);
        if(buyBackDO == null){
            return false;
        }
        List<BuyBackDetailDO> detialDOList = buyBackDetailMapper.list(buyBackDO.getId());
        if(ListUtil.isNullOrEmpty(detialDOList)){
            return false;
        }
        int total = 0;
        int some = 0;
        for(BuyBackDetailDO detailDO : detialDOList){
            if(detailDO.getQty().compareTo(detailDO.getSendQty()) == 0){
                total++;
            }else if(detailDO.getSendQty().compareTo(BigDecimal.ZERO) > 0){
                some++;
            }
        }
        BuyBackDO temp = new BuyBackDO();
        temp.setId(buyBackDO.getId());
        if(total == detialDOList.size()){
            temp.setSendStatus(2);
        }else if(some > 0 || total > 0){
            temp.setSendStatus(1);
        }else{
            temp.setSendStatus(0);
        }
        return buyBackMapper.update(temp)>0;
    }
    //更新创建出库单状态
    public boolean updateOutboundEnable(String backOrder, String orgId){
        BuyBackDO buyBackDO = buyBackMapper.getByOrderNo(backOrder);
        if(buyBackDO == null){
            return false;
        }
        List<BuyBackDetailDO> detialDOList = buyBackDetailMapper.list(buyBackDO.getId());
        if(ListUtil.isNullOrEmpty(detialDOList)){
            return false;
        }
        int total = 0;
        int some = 0;
        for(BuyBackDetailDO detailDO : detialDOList){
            if(detailDO.getQty().compareTo(detailDO.getCreateOutQty()) == 0){
                total++;
            }else if(detailDO.getCreateOutQty().compareTo(BigDecimal.ZERO) > 0){
                some++;
            }
        }
        BuyBackDO temp = new BuyBackDO();
        temp.setId(buyBackDO.getId());
        if(total == detialDOList.size()){
            temp.setCreateOutStatus(2);
        }else if(some > 0 || total > 0){
            temp.setCreateOutStatus(1);
        }else{
            temp.setCreateOutStatus(0);
        }
        return buyBackMapper.update(temp)>0;
    }
    /**
     * @Author: WangKe
     * @Description: 扫码入库时更新回购申请单主表和详情表相关记录状态
     * @Date: 2018/8/9 0009
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean updateByInBound(String backOrder, String materailNo, BigDecimal inAmount, String orgId)throws Exception{
        BuyBackDO buyBackDO = buyBackMapper.findByBackOrder(backOrder, orgId);
        if(buyBackDO == null){
            return false;
        }
        BuyBackDetailDO detailDO = buyBackDetailMapper.findBymaterialNo(buyBackDO.getId(), materailNo);
        if(detailDO == null){
            return false;
        }
        detailDO.setRealQty(detailDO.getRealQty().add(inAmount));
        if(detailDO.getRealQty().compareTo(detailDO.getQty()) >= 0){
            detailDO.setStatus(2);
        }else{
            detailDO.setStatus(1);
        }
        boolean success = buyBackDetailMapper.update(detailDO)>0;
        if(!success){
            return false;
        }

        //更新回购申请主表出库状态
        Integer status = 1;
        if(detailDO.getStatus() == 2){
            List<BuyBackDetailDO> detailDOList = buyBackDetailMapper.list(buyBackDO.getId());
            if(ListUtil.isNullOrEmpty(detailDOList)){
                return false;
            }
            status = 2;
            for(BuyBackDetailDO intentionDetailDO : detailDOList){
                if(!intentionDetailDO.getMaterialsNo().equals(materailNo) && intentionDetailDO.getStatus() != 2){
                    status = 1;
                    break;
                }
            }
        }
        buyBackDO.setInStatus(status);
        return buyBackMapper.update(buyBackDO)>0;
    }

    // 更新出库数量状态
    @Transactional(rollbackFor = Exception.class)
    public boolean updateByOutBound(String backOrder, String materailNo, BigDecimal inAmount, String orgId)throws Exception{
        BuyBackDO buyBackDO = buyBackMapper.findByBackOrder(backOrder, orgId);
        if(buyBackDO == null){
            return false;
        }
        BuyBackDetailDO detailDO = buyBackDetailMapper.findBymaterialNo(buyBackDO.getId(), materailNo);
        if(detailDO == null){
            return false;
        }
        detailDO.setOutQty(detailDO.getOutQty().add(inAmount));
        if(detailDO.getOutQty().compareTo(detailDO.getQty()) >= 0){
            detailDO.setOutStatus(2);
        }else{
            detailDO.setOutStatus(1);
        }
        boolean success = buyBackDetailMapper.update(detailDO)>0;
        if(!success){
            return false;
        }

        //更新回购申请主表出库状态
        Integer status = 1;
        if(detailDO.getOutStatus() == 2){
            List<BuyBackDetailDO> detailDOList = buyBackDetailMapper.list(buyBackDO.getId());
            if(ListUtil.isNullOrEmpty(detailDOList)){
                return false;
            }
            status = 2;
            for(BuyBackDetailDO intentionDetailDO : detailDOList){
                if(!intentionDetailDO.getMaterialsNo().equals(materailNo) && intentionDetailDO.getStatus() != 2){
                    status = 1;
                    break;
                }
            }
        }
        buyBackDO.setOutStatus(status);
        return buyBackMapper.update(buyBackDO)>0;
    }

    /**
     * @Author: WangKe
     * @Description: 回购入库手动结单时更新回购申请状态
     * @Date: 2018/8/9 0009
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean updateByManulFinish(BackInboundDO inboundDO, String materialNo, String orgId)throws Exception{
        if(inboundDO == null){
            return false;
        }
        List<BackInboundDetailDO> inboundDetailDOList = backInboundDetailMapper.list(inboundDO.getId());
        if(ListUtil.isNullOrEmpty(inboundDetailDOList)){
            return false;
        }

        BuyBackDO buyBackDO = buyBackMapper.findByBackOrder(inboundDO.getBackOrder(), orgId);
        if(buyBackDO == null){
            return false;
        }
        List<BuyBackDetailDO> detailDOList = buyBackDetailMapper.list(buyBackDO.getId());
        if(ListUtil.isNullOrEmpty(detailDOList)){
            return false;
        }

        boolean success;
        BigDecimal sub;
        for(BuyBackDetailDO buyBackDetailDO : detailDOList){
            if(!StringUtil.isNullOrEmpty(materialNo) && !materialNo.equals(buyBackDetailDO.getMaterialsNo())){
                continue;
            }
            for(BackInboundDetailDO inboundDetailDO : inboundDetailDOList){
                if(buyBackDetailDO.getMaterialsNo().equals(inboundDetailDO.getMaterialsNo())){
                    if(inboundDetailDO.getStatus() != 2 && inboundDetailDO.getStatus() != 3){
                        sub = inboundDetailDO.getAmount().subtract(inboundDetailDO.getRealAmount());
                        buyBackDetailDO.setSendQty(buyBackDetailDO.getSendQty().subtract(sub));

                        success = buyBackDetailMapper.update(buyBackDetailDO)>0;
                        if(!success){
                            throw new Exception("更新回购申请详情失败");
                        }

                        //更新其他回购入库单的已入库意向数量
                        success = backInboundDetailMapper.updateSendQty(inboundDO.getBackOrder(), inboundDetailDO.getMaterialsNo(),
                                buyBackDetailDO.getSendQty(), inboundDO.getOrgId())>0;
                        if(!success){
                            throw new Exception("更新回购申请详情失败");
                        }
                    }
                }
            }
        }

        detailDOList = buyBackDetailMapper.list(buyBackDO.getId());
        int total = 0;
        int some = 0;
        for(BuyBackDetailDO buyBackDetailDO : detailDOList){
            if(buyBackDetailDO.getQty().compareTo(buyBackDetailDO.getSendQty()) == 0){
                total++;
            }
            if(buyBackDetailDO.getSendQty().compareTo(BigDecimal.ZERO) > 0){
                some++;
            }
        }

        BuyBackDO temp = new BuyBackDO();
        temp.setId(buyBackDO.getId());
        if(total == detailDOList.size()){
            temp.setSendStatus(2);
        }else if(some > 0){
            temp.setSendStatus(1);
        }else{
            temp.setSendStatus(0);
        }
        return buyBackMapper.update(temp)>0;
    }

    /**
     * @Description: 回购出库手动结单时更新回购申请状态
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean updateOutboundByManulFinish(BackOutboundDO outboundDO, String materialNo, String orgId)throws Exception{
        if(outboundDO == null){
            return false;
        }
        List<BackOutboundDetailDO> outboundDetailDOList = backOutboundDetailMapper.list(outboundDO.getId());
        if(ListUtil.isNullOrEmpty(outboundDetailDOList)){
            return false;
        }

        BuyBackDO buyBackDO = buyBackMapper.findByBackOrder(outboundDO.getBackOrder(), orgId);
        if(buyBackDO == null){
            return false;
        }
        List<BuyBackDetailDO> detailDOList = buyBackDetailMapper.list(buyBackDO.getId());
        if(ListUtil.isNullOrEmpty(detailDOList)){
            return false;
        }

        boolean success;
        BigDecimal sub;
        for(BuyBackDetailDO buyBackDetailDO : detailDOList){
            if(!StringUtil.isNullOrEmpty(materialNo) && !materialNo.equals(buyBackDetailDO.getMaterialsNo())){
                continue;
            }
            for(BackOutboundDetailDO inboundDetailDO : outboundDetailDOList){
                if(buyBackDetailDO.getMaterialsNo().equals(inboundDetailDO.getMaterialsNo())){
                    if(inboundDetailDO.getStatus() != 2 && inboundDetailDO.getStatus() != 3){
                        sub = inboundDetailDO.getAmount().subtract(inboundDetailDO.getRealAmount());
                        buyBackDetailDO.setCreateOutQty(buyBackDetailDO.getCreateOutQty().subtract(sub));

                        success = buyBackDetailMapper.update(buyBackDetailDO)>0;
                        if(!success){
                            throw new Exception("更新回购申请详情失败");
                        }

                        //更新其他回购入库单的已入库意向数量
                        success = backOutboundDetailMapper.updateSendQty(outboundDO.getBackOrder(), inboundDetailDO.getMaterialsNo(),
                                buyBackDetailDO.getCreateOutQty(), outboundDO.getOrgId())>0;
                        if(!success){
                            throw new Exception("更新回购申请详情失败");
                        }
                    }
                }
            }
        }

        detailDOList = buyBackDetailMapper.list(buyBackDO.getId());
        int total = 0;
        int some = 0;
        for(BuyBackDetailDO buyBackDetailDO : detailDOList){
            if(buyBackDetailDO.getQty().compareTo(buyBackDetailDO.getCreateOutQty()) == 0){
                total++;
            }
            if(buyBackDetailDO.getCreateOutQty().compareTo(BigDecimal.ZERO) > 0){
                some++;
            }
        }

        BuyBackDO temp = new BuyBackDO();
        temp.setId(buyBackDO.getId());
        if(total == detailDOList.size()){
            temp.setCreateOutStatus(2);
        }else if(some > 0){
            temp.setCreateOutStatus(1);
        }else{
            temp.setCreateOutStatus(0);
        }
        return buyBackMapper.update(temp)>0;
    }
}
